home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / p_aa4re / mbb35src / 8530svc.asm < prev    next >
Encoding:
Assembly Source File  |  1987-12-06  |  69.1 KB  |  1,485 lines

  1. ;==========================================================================;
  2. ; 8530 Services                                                            ;
  3. ;                                                                          ;
  4. ;   Copyright 1986, 1987 by H. Roy Engehausen.  All rights reserved.       ;
  5. ;   This software may be freely distributed and used, but it may not       ;
  6. ;   under any circumstances be sold by anyone other than the author.       ;
  7. ;   It may be distributed by a commercial company as long as it is         ;
  8. ;   for no cost.                                                           ;
  9. ;                                                                          ;
  10. ;   Permission is explicity granted to use this code as a model for        ;
  11. ;   other programs requiring interrupt driven serial I/O as long as they   ;
  12. ;   carry this copyright notice and the imbedded constants                 ;
  13. ;                                                                          ;
  14. ;      These run disabled for the most part because of the nature of       ;
  15. ;      reading and writing the 8530.                                       ;
  16. ;                                                                          ;
  17. ; AL = parameter                                                           ;
  18. ; AH = opcode                                                              ;
  19. ; BL = COM number - 1 (0 = COM1, 1=COM2, ...)                              ;
  20. ;                                                                          ;
  21. ; Opcode 0 -- Initialize                                                   ;
  22. ;       Parms                                                              ;
  23. ;         xxx..... = Data rate.  Use same settings as IBM ROM BIOS.        ;
  24. ;                    300 bps = 2, 1200 bps= 4.                             ;
  25. ;                                                                          ;
  26. ;         ...x.... = Full duplex if 1.  Half duplex if 0.                  ;
  27. ;                                                                          ;
  28. ;         ....x... = Error packet handler.  0 = throw away all error       ;
  29. ;                    packets.                                              ;
  30. ;                                                                          ;
  31. ;         .....xxx = Don't care.  Use 0 for now!                           ;
  32. ;                                                                          ;
  33. ;       Special case -- If AL = 0 then the COM port is closed!             ;
  34. ;                                                                          ;
  35. ; Opcode 1+2 -- Same as ASYNC ports but conforms to KISS interface         ;
  36. ;                                                                          ;
  37. ; Opcode 3 -- Status                                                       ;
  38. ;       No parms                                                           ;
  39. ;       Returns AH.  AL = 0                                                ;
  40. ;         x.xxxxx. = not assigned.  Zero                                   ;
  41. ;         .x...... = If 0 then packets remain in the transmit queue        ;
  42. ;         .......x = If 1 then packets await in the receive queue          ;
  43. ;                                                                          ;
  44. ; Opcode 10 -- Send a packet                                               ;
  45. ;       ES = Segment of buffer containing the packet to be sent.           ;
  46. ;       Note:  The buffer pointed to by ES will be freed when the          ;
  47. ;       packet is sent.  It should be gotten via Opcode 6.  It must        ;
  48. ;       be 512 bytes long and conform to the layout of the buffers         ;
  49. ;                                                                          ;
  50. ; Opcode 11 -- Receive a packet                                            ;
  51. ;       Returns ES with segment of buffer containing the packet            ;
  52. ;       recieved.  If zero, no such packet exists.                         ;
  53. ;                                                                          ;
  54. ; Opcode 12 -- Buffer management                                           ;
  55. ;       If ES is zero then returns a buffer segment in ES.                 ;
  56. ;       If ES is non-zero then the buffer pointed to is freed.             ;
  57. ;                                                                          ;
  58. ; Opcode 13 -- Set TXD -- time from RTS to start of packet.                ;
  59. ;       AL = new setting in clock counts                                   ;
  60. ;                                                                          ;
  61. ; Opcode 14 -- Set P -- Controls time from end of DCD to RTS               ;
  62. ;       AL = new setting.  1.0 = 255                                       ;
  63. ;                                                                          ;
  64. ; Opcode 15 -- Set slot time  -- Controls time from end of DCD to RTS      ;
  65. ;       AL = new setting in clock counts                                   ;
  66. ;                                                                          ;
  67. ; Opcode 16 -- Set CRC wait -- time from start of last character to drop   ;
  68. ;                             RTS.. Should be 5 character lengths minimum  ;
  69. ;       AL = new setting in clock counts                                   ;
  70. ;                                                                          ;
  71. ;==========================================================================;
  72.  
  73. rcvbuf_8530 EQU 00000001B           ; Receive buffer has data in it
  74. txbuf_8530  EQU 10111111B           ; Transmit buffer has data in it (inverted)
  75.  
  76.         CLI                         ; Interrupts off!
  77.  
  78.         MOV     BL,AH               ; Use BX so we can jump
  79.         SUB     BH,BH               ; Use BX so we can jump
  80.         CMP     BL,16               ; Legal value?
  81.         JA      svc_8530_not_us     ;      Nope.. Pass on down
  82.         SHL     BL,1                ; *2 for words
  83.         JMP     DS:svc_8530_br[BX]  ; Go where we gotta go
  84.  
  85. svc_8530_not_us:                    ;
  86.         JMP     rsint_exit_not_us   ;
  87.  
  88. svc_8530_br LABEL WORD              ;
  89.  
  90.         DW      OFFSET rsint_8530_init   ; 0 = Init
  91.         DW      OFFSET rsint_8530_kiss_t ; 1 = Send character
  92.         DW      OFFSET rsint_8530_kiss_r ; 2 = Rcv character
  93.         DW      OFFSET rsint_8530_status ; 3 = Status
  94.         DW      OFFSET rsint_8530_query  ; 4 = Query
  95.         DW      OFFSET rsint_8530_ignore ; 5 = Nothing
  96.         DW      OFFSET rsint_8530_ignore ; 6 = Nothing
  97.         DW      OFFSET rsint_8530_ignore ; 7 = Nothing
  98.         DW      OFFSET rsint_8530_ignore ; 8 = Nothing
  99.         DW      OFFSET rsint_8530_ignore ; 9 = Nothing
  100.         DW      OFFSET rsint_8530_sendp  ; 10 = Send Packet
  101.         DW      OFFSET rsint_8530_recvp  ; 11 = Receive Packet
  102.         DW      OFFSET rsint_8530_buff   ; 12 = Get/Free buffer
  103.         DW      OFFSET rsint_8530_txd    ; 13 = Set TXD
  104.         DW      OFFSET rsint_8530_setp   ; 14 = Set P
  105.         DW      OFFSET rsint_8530_slot   ; 15 = Set slot
  106.         DW      OFFSET rsint_8530_crcwt  ; 16 = Set CRC wait
  107.  
  108. rsint_8530_ignore:
  109.         MOV     AX,0FFFFH           ; All ones for error
  110.         JMP     rsint_exit          ;
  111.  
  112. ;==========================================================================;
  113. ; Inquiry                                                                  ;
  114. ;==========================================================================;
  115.  
  116. rsint_8530_query:
  117.  
  118.         MOV     AX,0AA55H           ; Set footprint
  119.         JMP     rsint_exit          ; All done
  120.  
  121. ;--------------------------------------------------------------------------;
  122. ; Speed tables for 8530 PACCOMM board.  Entries are in the same order as   ;
  123. ; original BIOS                                                            ;
  124. ;                                                                          ;
  125. ; 1st table = Divisor when DPLL is on  (X32 clock)                         ;
  126. ; 2nd table = Divisor when DPLL is off (X1  clock)                         ;
  127. ; 3nd table = Data rate table -- Type "B" card                             ;
  128. ; 4rd table = Modem setting -- 7910 -- Type "A" card                       ;
  129. ; 5th table = Modem setting -- 7910 -- Type "B" card                       ;
  130. ; 6th table = Modem setting -- TCM3105 -- Type "B" card                    ;
  131. ;                                                                          ;
  132. ;--------------------------------------------------------------------------;
  133.  
  134. divx32_8530 LABEL WORD          ; 7910 clock data for X32 and 2.4576 xtal
  135.  
  136.         DW      015BH           ;  110 bps - X32 clock - 0
  137.         DW      00FEH           ;  150 bps - X32 clock - 1
  138.         DW      007EH           ;  300 bps - X32 clock - 2
  139.         DW      003EH           ;  600 bps - X32 clock - 3
  140.         DW      001EH           ; 1200 bps - X32 clock - 4
  141.         DW      000EH           ; 2400 bps - X32 clock - 5
  142.         DW      0006H           ; 4800 bps - X32 clock - 6
  143.         DW      0002H           ; 9600 bps - X32 clock - 7
  144.  
  145. divx1_8530 LABEL WORD           ; 7910 clock data for X1 and 2.4576 Mhz xtal
  146.  
  147.         DW      26A0H           ;  110 bps - X1 clock
  148.         DW      1FFCH           ;  150 bps - X1 clock
  149.         DW      0FFCH           ;  300 bps - X1 clock
  150.         DW      07FEH           ;  600 bps - X1 clock
  151.         DW      03FEH           ; 1200 bps - X1 clock
  152.         DW      01FEH           ; 2400 bps - X1 clock
  153.         DW      00FEH           ; 4800 bps - X1 clock
  154.         DW      007EH           ; 9600 bps - X1 clock
  155.  
  156. divdr_8530 LABEL WORD           ; Corresponds table value to data rate
  157.                                 ; times 64 and divided by 10.  Used to
  158.                                 ; calculate divider setting
  159.  
  160.         DW       704            ;  110 bps
  161.         DW       960            ;  150 bps
  162.         DW      1920            ;  300 bps
  163.         DW      3840            ;  600 bps
  164.         DW      7680            ; 1200 bps
  165.         DW      15360           ; 2400 bps
  166.         DW      30720           ; 4800 bps
  167.         DW      61440           ; 9600 bps
  168.  
  169. modem_8530_a1 LABEL BYTE        ; Type "A" card 7910 Modem bits...
  170.                                 ;     Bottom 4 bits are:
  171.                                 ;          MC3, MC2, MC1, MC0
  172.                                 ;     The 7910 is on both channels
  173.  
  174.         DB      01H             ;  110 bps - Modem setting -- 103 Answer
  175.         DB      01H             ;  150 bps - Modem setting -- 103 Answer
  176.         DB      01H             ;  300 bps - Modem setting -- 103 Answer
  177.         DB      02H             ;  600 bps - Modem setting -- 202
  178.         DB      02H             ; 1200 bps - Modem setting -- 202
  179.         DB      02H             ; 2400 bps - Modem setting -- 202 Probably
  180.         DB      02H             ; 4800 bps - Modem setting -- 202 won't
  181.         DB      02H             ; 9600 bps - Modem setting -- 202 work
  182.  
  183. modem_8530_b1 LABEL BYTE        ; Type "B" card 7910 Modem bits...
  184.                                 ;     Bottom 4 bits are:
  185.                                 ;         MC0, MC2, MC1, MC3
  186.                                 ;     The 7910 is on "A" channel only
  187.  
  188.         DB      08H             ;  110 bps - Modem setting -- 103 Answer
  189.         DB      08H             ;  150 bps - Modem setting -- 103 Answer
  190.         DB      08H             ;  300 bps - Modem setting -- 103 Answer
  191.         DB      02H             ;  600 bps - Modem setting -- 202
  192.         DB      02H             ; 1200 bps - Modem setting -- 202
  193.         DB      02H             ; 2400 bps - Modem setting -- 202 Probably
  194.         DB      02H             ; 4800 bps - Modem setting -- 202 won't
  195.         DB      02H             ; 9600 bps - Modem setting -- 202 work
  196.  
  197.                                 ; Note.. The high order bit controls loopback
  198.                                 ; mode.  It is forced on.  All this does is
  199.                                 ; make the tones use the same pair for both
  200.                                 ; transmit and receive
  201.  
  202. modem_8530_b2 LABEL BYTE        ; Type "B" card TCM3105 Modem Bits
  203.                                 ;     Upper 4 bits are:
  204.                                 ;       special, TRS(thru J3), TXR1, TXR2
  205.                                 ;     The 3105 is on "B" channel only
  206.                                 ;     The special bit is the 7910 loop back
  207.                                 ;     bit and we force it on!
  208.  
  209.         DB      00H             ; Only one setting for this sucker!
  210.                                 ;      Bell 202, 1200 bps
  211.  
  212. word_100 DW     100             ; This constant is here so we can divide later
  213.  
  214. ;==========================================================================;
  215. ; Init..                                                                   ;
  216. ;     The init character is similar to the one for BIOS                    ;
  217. ;        xxx..... -- Baud rate.  Same meanings as for BIOS                 ;
  218. ;        ...000.. -- Must be zero!                                         ;
  219. ;        ......x. -- Passthru packets in error if on                       ;
  220. ;        .......x -- Full duplex if on                                     ;
  221. ;                                                                          ;
  222. ; If AL is all zero then disable the channel                               ;
  223. ;                                                                          ;
  224. ;==========================================================================;
  225.  
  226. rsint_8530_init:
  227.  
  228. ;--------------------------------------------------------------------------;
  229. ; Special check for off!  If it is, do it                                  ;
  230. ;--------------------------------------------------------------------------;
  231.  
  232.         OR      AL,AL               ; Turn off?
  233.         JNZ     rsint_8530_i_go     ;      Nope..  Initialize the thing
  234.  
  235.         AND     flags,0FFH-flags_in_use  ; This block is closed!
  236.  
  237.         MOV     DX,baseaddr[SI]     ; Get port address
  238.         CALL    off_8530            ; Disable this channel
  239.  
  240.         JMP     rsint_exit          ; Leave
  241.  
  242. rsint_8530_i_go:                    ;
  243.  
  244.         MOV     flags[SI],flags_in_use  ; This block is open!
  245.  
  246. ;--------------------------------------------------------------------------;
  247. ; Set options                                                              ;
  248. ;--------------------------------------------------------------------------;
  249.  
  250.         MOV     BL,AL               ; Get the options bits
  251.         AND     BL,00011111B        ; Remove baud rate parameter
  252.         MOV     BH,options[SI]      ; Get current options
  253.         AND     BH,11100000B        ; Remove the ones we are about to set
  254.         OR      BL,BH               ; Make new options byte
  255.         MOV     options[SI],BL      ; And save
  256.  
  257. ;--------------------------------------------------------------------------;
  258. ; Initialize the modem                                                     ;
  259. ;--------------------------------------------------------------------------;
  260.  
  261.         MOV     DX,baseaddr[SI]      ; Get port address
  262.  
  263.         MOV     CL,5                ; Get baud rate parameter
  264.         SHR     AL,CL               ;
  265.         AND     AX,07H              ;
  266.  
  267.         MOV     data_rate[SI],AL    ; Save baud rate
  268.         MOV     BX,AX               ; Put baud rate into work register
  269.  
  270.         MOV     AH,modem_8530_a1[BX] ; Get the new modem setting for type "A"
  271.         CMP     type_8530[SI],type_8530_a ; Type "A" card?
  272.         JE      rsinit_8530_modem_do ;      Yep!
  273.  
  274.                                      ; Must be a type "B" card to get here
  275.  
  276.         MOV     AH,modem_8530_b1[BX] ; Get the new 7910 modem setting for "B"
  277.         TEST    DX,scc_chan_mask     ; Channel "A" or "B"
  278.         JNZ     rsinit_8530_modem_do ;      Channel "A" -- 7910!
  279.  
  280.         MOV     AH,modem_8530_b2     ; Type "B" 3105 modem setting (only one)
  281.  
  282. rsinit_8530_modem_do:               ; AH = new modem setting when we get here
  283.  
  284.         MOV     DI,chip_comm[SI]    ; Get chip common pointer
  285.         MOV     AL,DS:4[DI]         ; Get current byte setting
  286.  
  287.         TEST    DX,scc_chan_mask    ; Channel "A" or "B"
  288.         JNZ     rsinit_8530ia       ; Channel "A"
  289.  
  290.         AND     AL,0F0H             ; Remove old channel "B" setting
  291.         OR      AL,AH               ; Put in the modem setting
  292.         JMP     SHORT rsinit_8530_modem_set ; Go init the modem
  293.  
  294. rsinit_8530ia:
  295.         AND     AL,0FH              ; Remove old channel "A" setting
  296.         MOV     CL,4                ;
  297.         SHL     AH,CL               ; Shift it to where it belongs
  298.         OR      AL,AH               ; and form the new modem setting
  299.  
  300. rsinit_8530_modem_set:
  301.  
  302.         MOV     DS:4[DI],AL         ; Save the new modem setting
  303.  
  304. ; Channel A setting is in top half of AL
  305. ; Channel B setting is in bottom half of AL
  306. ; This is backwards for the "TYPE B" card
  307.  
  308.         CMP     type_8530[SI],type_8530_a ; Type "A" card?
  309.         JE      rsinit_8530_modem_set2    ; Yep!
  310.  
  311.         MOV     CL,4                ; Rotate the register to flip flop the
  312.         ROR     AL,CL               ; A and B channels
  313.         OR      AL,10000000B        ; Turn on M4 bit always.  This forces the
  314.                                     ; the 7910 into loopback mode.
  315.  
  316. rsinit_8530_modem_set2:
  317.  
  318.         AND     DX,scc_card_mask    ; Back to address of card
  319.         ADD     DX,scc_modem        ; Now change to modem address
  320.         OUT     DX,AL               ; Set the modems
  321.  
  322. ;--------------------------------------------------------------------------;
  323. ; Setup 8530 -- Register 9 -- Reset the channel..                          ;
  324. ;--------------------------------------------------------------------------;
  325.  
  326.         MOV     DX,baseaddr[SI]     ; Get port address
  327.  
  328.         MOV     AL,sccreg9          ; Point at WR9
  329.         OUT     DX,AL               ;
  330.  
  331.         MOV     AL,chareset         ; Guess Channel A reset
  332.         TEST    DX,scc_chan_mask    ; Channel "A" or "B"
  333.         JNZ     rsinit_8530ra       ;      Channel "A"
  334.         MOV     AL,chbreset         ; Wrong guess -- Channel B reset
  335. rsinit_8530ra:                      ;
  336.  
  337.         OUT     DX,AL               ;
  338.  
  339. ;--------------------------------------------------------------------------;
  340. ; Setup 8530 -- Register 6 -- SDLC Address field                           ;
  341. ;            None                                                          ;
  342. ;--------------------------------------------------------------------------;
  343.  
  344.         MOV     DX,baseaddr[SI]     ; Get port address
  345.  
  346.         MOV     AL,sccreg6          ; Point at WR6
  347.         OUT     DX,AL               ;
  348.         SUB     AL,AL               ; Zero
  349.         OUT     DX,AL               ;
  350.  
  351. ;--------------------------------------------------------------------------;
  352. ; Setup 8530 -- Register 7 -- SDLC Flag                                    ;
  353. ;            01111110                                                      ;
  354. ;--------------------------------------------------------------------------;
  355.  
  356.         MOV     AL,sccreg7          ; WR7
  357.         OUT     DX,AL               ;
  358.         MOV     AL,01111110B        ;
  359.         OUT     DX,AL               ;
  360.  
  361. ;------------------------------------+-------------------------------------;
  362. ; Setup 8530 -- Register 10 -- Data type                                   ;
  363. ;            CRC preset 1, NRZI, abort on underrun                         ;
  364. ;--------------------------------------------------------------------------;
  365.  
  366.         MOV     AL,sccreg10         ; WR10
  367.         OUT     DX,AL               ;
  368.         MOV     AL,crc_1or0+nrzimode;
  369.         OUT     DX,AL               ;
  370.  
  371. ;--------------------------------------------------------------------------;
  372. ; Setup 8530 -- Register 4 -- Mode                                         ;
  373. ;       Use 01x, SDLC, no parity                                           ;
  374. ;--------------------------------------------------------------------------;
  375.  
  376.         MOV     AL,sccreg4          ; Point at WR4
  377.         OUT     DX,AL               ;
  378.         MOV     AL,x1_clck+sync_sdl+sync_mod ;
  379.         OUT     DX,AL               ; Put out
  380.  
  381. ;--------------------------------------------------------------------------;
  382. ; Setup 8530 -- If this is channel "A" and channel "B" has not been set    ;
  383. ; then we have to init the clock registers over there to supply XTAL to    ;
  384. ; everyone.  This only applies to the PACCOMM type "A" card.               ;
  385. ;--------------------------------------------------------------------------;
  386.  
  387.         MOV     DI,chip_comm[SI]    ; Get chip common pointer
  388.  
  389.         CMP     type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
  390.         JNE     rsinit_8530cb       ;      Nope!
  391.  
  392.  
  393.         TEST    DX,scc_chan_mask    ; Channel "A" or "B"
  394.         JZ      rsinit_8530cb       ;      Channel "B"
  395.  
  396.         CMP     DS:BYTE PTR 5[DI],0 ; Channel "B" started?
  397.         JNE     rsinit_8530cb       ;      Channel "B"
  398.  
  399.         AND     DL,0FFH-scc_chan_mask ; Channel "B" now
  400.         MOV     AL,sccreg11         ; Point at WR11
  401.         OUT     DX,AL               ;
  402.         MOV     AL,xtal_osc+rxc_brg+txc_brg+trxc_out+trxc_xtl ;
  403.         OUT     DX,AL               ; Put out
  404.         OR      DL,scc_chan_mask    ; Back to channel "A"
  405.  
  406. rsinit_8530cb:
  407.  
  408.         MOV     DS:BYTE PTR 5[DI],1 ; Channel "B" started!
  409.  
  410. ;--------------------------------------------------------------------------;
  411. ; Setup 8530 -- Do the clock and receiver                                  ;
  412. ;--------------------------------------------------------------------------;
  413.  
  414.         CALL    ron_clk_8530        ; Receiver and clock setup
  415.  
  416. ;--------------------------------------------------------------------------;
  417. ; Setup 8530 -- Register 5                                                 ;
  418. ;            DTR on, 8 bits for transmit, transmit CRC enable, tx enable   ;
  419. ;--------------------------------------------------------------------------;
  420.  
  421.         MOV     AL,sccreg5          ; Point at WR5
  422.         OUT     DX,AL               ;
  423.         MOV     AL,dtr_pin+tx_8bits+tx_crcen+tx_enabl ;
  424.         OUT     DX,AL               ; Transmit
  425.  
  426. ;--------------------------------------------------------------------------;
  427. ; Setup Interrupts                                                         ;
  428. ;--------------------------------------------------------------------------;
  429.  
  430.         CALL    int_8530            ;
  431.  
  432. ;--------------------------------------------------------------------------;
  433. ; Setup 8530 -- Register 9 -- Master interrupt control                     ;
  434. ;            Enable, no vector, status wanted                              ;
  435. ;--------------------------------------------------------------------------;
  436.  
  437.         MOV     AL,sccreg9          ; Point at WR9
  438.         OUT     DX,AL               ;
  439.         MOV     AL,int_enab+no_vectr+enab_vis ;
  440.         OUT     DX,AL               ;
  441.  
  442. ;--------------------------------------------------------------------------;
  443. ; Init all done                                                            ;
  444. ;--------------------------------------------------------------------------;
  445.  
  446.         JMP     rsint_exit          ;
  447.  
  448. ;==========================================================================;
  449. ; Send a character in KISS mode                                            ;
  450. ;==========================================================================;
  451.  
  452. rsint_8530_kiss_t:
  453.  
  454.         MOV     BX,buffer_t_in[SI]  ; Get buffer counter
  455.  
  456. ;--------------------------------------------------------------------------;
  457. ; This code handles the character after an escape                          ;
  458. ;--------------------------------------------------------------------------;
  459.  
  460.         TEST    kiss_flag[SI],kiss_r_fesc ; Escape was previous?
  461.         JZ      rsint_8530_kt_nescp ;            Nope....
  462.  
  463.         CMP     AL,kiss_tfesc       ; Transposed FESC?
  464.         JNE     rsint_8530_kt_ntfesc ;    Nope....
  465.         MOV     AL,kiss_fesc        ; Make an FESC
  466.         JMP     rsint_8530_kt_data  ; and handle like data
  467.  
  468. rsint_8530_kt_ntfesc:
  469.  
  470.         CMP     AL,kiss_tfesc       ; Transposed FEND?
  471.         JNE     rsint_8530_kt_nescp ;     Nope....  Just pass thru
  472.         MOV     AL,kiss_fend        ; Make an FEND
  473.         JMP     rsint_8530_kt_data  ; and handle like data
  474.  
  475. rsint_8530_kt_nescp:
  476.  
  477. ;--------------------------------------------------------------------------;
  478. ; Check for FEND                                                           ;
  479. ;--------------------------------------------------------------------------;
  480.  
  481.         CMP     AL,kiss_fend        ; Is the incoming data FEND?
  482.         JE      rsint_8530_kt_isfend  ;   Yes.....
  483.         JMP     rsint_8530_kt_notfend ;   Nope....
  484. rsint_8530_kt_isfend:
  485.  
  486. ;--------------------------------------------------------------------------;
  487. ; Incoming character is FEND.. It either starts or ends a packet.          ;
  488. ;--------------------------------------------------------------------------;
  489.  
  490.         OR      BX,BX               ; Is buffer counter zero?
  491.         JNZ     rsint_8530_kt_notstart ;   No... Must be an end of frame
  492.         JMP     rsint_8530_kt_start ;      Yes.. Must be a start of frame
  493. rsint_8530_kt_notstart:
  494.  
  495. ;--------------------------------------------------------------------------;
  496. ; Incoming character is FEND.. It ends a packet...                         ;
  497. ;--------------------------------------------------------------------------;
  498.  
  499.         CMP     kiss_type[SI],kiss_data ; Is this a data packet
  500.         JNE     rsint_8530_kt_cmd   ;          Nope... Its a command
  501.  
  502.         MOV     ES,buffer_t_seg[SI] ; Get buffer's address
  503.         MOV     ES:buffer_dl,BX     ; Set length
  504.  
  505.         MOV     buffer_t_seg[SI],0  ; Clear buffer pointer
  506.         MOV     buffer_t_in[SI],0   ; Clear buffer counter
  507.  
  508.         JMP     rsint_8530_sendp    ; Send the packet
  509.  
  510. ;--------------------------------------------------------------------------;
  511. ; This code handles a stream from the host that has a KISS command and     ;
  512. ; not data in it.                                                          ;
  513. ;--------------------------------------------------------------------------;
  514.  
  515. rsint_8530_kt_cmd:
  516.  
  517.         MOV     buffer_t_in[SI],0   ; Clear buffer counter
  518.         AND     kiss_flag[SI],0FFH-kiss_r_fesc ; Turn off escape flag
  519.  
  520.         TEST    kiss_flag[SI],kiss_t_valid ; Type valid?
  521.         JZ      rsint_8530_kt_i     ;             No.... Ignore packet
  522.         AND     kiss_flag[SI],0FFH-kiss_t_valid ; Turn off type flag
  523.  
  524.         MOV     BL,kiss_type[SI]    ; Get type
  525.  
  526.         CMP     BL,kiss_fesc        ; Is this an escape command
  527.         JE      rsint_8530_kt_i     ;      Yes... Ignore packet
  528.  
  529.         MOV     ES,buffer_t_seg[SI] ; Get the buffer address
  530.         MOV     AL,ES:0             ; Get the data byte
  531.         SUB     AH,AH               ; Clear type of the word
  532.  
  533.         SUB     BH,BH               ; Make the type a word
  534.         DEC     BL                  ; Base of index = 1 so make 0
  535.         SHL     BL,1                ; And make it address a word
  536.         JMP     DS:rsint_8530_kt_j[BX] ; Go where we gotta go
  537.  
  538. rsint_8530_kt_j LABEL WORD          ;
  539.  
  540.         DW   OFFSET rsint_8530_kt_txd  ; 1 = TXD
  541.         DW   OFFSET rsint_8530_kt_p    ; 2 = P
  542.         DW   OFFSET rsint_8530_kt_slot ; 3 = Slot time
  543.         DW   OFFSET rsint_8530_kt_crc  ; 4 = TxTail (CRC time)
  544.         DW   OFFSET rsint_8530_kt_fds  ; 5 = Full duplex switch
  545.         DW   OFFSET rsint_8530_kt_i    ; 6 = Set link speed
  546.  
  547. rsint_8530_kt_i:                    ; Come here to ignore the command
  548.         JMP     rsint_8530_status   ;
  549.  
  550. five    DB      5                   ; Needed for divide
  551.  
  552. rsint_8530_kt_txd:                  ; Set TXD - value in 10ms increments
  553.         ADD     AL,3                ; Change value to 50ms increments.  This
  554.         DIV     five                ; is close to our 54ms clock pulses
  555.         CBW                         ; Need to store a word
  556.         OR      AX,AX               ; Don't store zero!
  557.         JNZ     rsint_8530_kt_txd_ok; If the user tries this,
  558.         MOV     AX,1                ;      use 1 instead
  559. rsint_8530_kt_txd_ok:
  560.         MOV     value_txd[SI],AX    ; Set TXD
  561.         JMP     rsint_8530_status   ; Exit
  562.  
  563. rsint_8530_kt_p:                    ; Set P
  564.         MOV     value_p[SI],AL      ;
  565.         JMP     rsint_8530_status   ; Exit
  566.  
  567. rsint_8530_kt_slot:                 ; Set Slot time - value in 10ms increments
  568.         ADD     AL,3                ; Change value to 50ms increments.  This
  569.         DIV     five                ; is close to our 54ms clock pulses
  570.         OR      AL,AL               ; Don't store zero!
  571.         JNZ     rsint_8530_kt_slot_ok; If the user tries this,
  572.         MOV     AL,1                ;      use 1 instead
  573. rsint_8530_kt_slot_ok:
  574.         MOV     value_slot[SI],AL   ; Set slot
  575.         JMP     rsint_8530_status   ; Exit
  576.  
  577. rsint_8530_kt_crc:                  ; Set CRC - value in 10ms increments
  578.         ADD     AL,3                ; Change value to 50ms increments.  This
  579.         DIV     five                ; is close to our 54ms clock pulses
  580.         CBW                         ; Need to store a word
  581.         OR      AX,AX               ; Don't store zero!
  582.         JNZ     rsint_8530_kt_crc_ok; If the user tries this,
  583.         MOV     AX,1                ;      use 1 instead
  584. rsint_8530_kt_crc_ok:
  585.         MOV     value_crc[SI],AX    ; Set CRC
  586.         JMP     rsint_8530_status   ; Exit
  587.  
  588. rsint_8530_kt_fds:                  ; Set full duplex switch
  589.         MOV     AH,options[SI]      ; Get options switch
  590.         AND     AH,0FFH-opt_fd      ; Remove old setting
  591.         OR      AL,AL               ; Turn switch on or off?
  592.         JZ      rsint_8530_kt_fds_0 ;      Switch is off
  593.         OR      AH,opt_fd           ;      Switch is on
  594. rsint_8530_kt_fds_0:
  595.         MOV     options[SI],AH      ; Put the switch back
  596.         JMP     rsint_8530_status   ; Exit
  597.  
  598. ;--------------------------------------------------------------------------;
  599. ; Incoming character is FEND.. It may start a packet                       ;
  600. ;--------------------------------------------------------------------------;
  601.  
  602. rsint_8530_kt_start:                ;
  603.  
  604.         AND     kiss_flag[SI],0FFH-kiss_t_valid-kiss_r_fesc ; Turn off type
  605.                                           ; and escape flags
  606.         MOV     kiss_type[SI],kiss_escape ; Set type to escape
  607.  
  608.         JMP     rsint_8530_status   ; Send staus back
  609.  
  610. ;--------------------------------------------------------------------------;
  611. ; Incoming character is not FEND.. Handle first character in packet if it  ;
  612. ; is one                                                                   ;
  613. ;--------------------------------------------------------------------------;
  614.  
  615. rsint_8530_kt_notfend:
  616.  
  617.         OR      BX,BX               ; Is buffer counter zero?
  618.         JNZ     rsint_8530_kt_data  ;      No... Can't be first byte.  Its data
  619.         TEST    kiss_flag[SI],kiss_t_valid ; Type loaded?
  620.         JNZ     rsint_8530_kt_data  ;          Yes.. This is the first data byte
  621.  
  622.         CMP     AL,kiss_escape      ; Is this KISS escape
  623.         JE      rsint_8530_kt_okt   ;      Yep... Type ok
  624.  
  625.         CMP     AL,kiss_last_type   ; Is this within the valid modes?
  626.         JBE     rsint_8530_kt_okt   ;      Yep... Mode ok
  627.  
  628.         MOV     AL,kiss_escape      ; Invalid type.. Use escape
  629.  
  630. rsint_8530_kt_okt:
  631.  
  632.         MOV     kiss_type[SI],AL    ; Set the incoming data type
  633.         OR      kiss_flag[SI],kiss_t_valid ; Type valid
  634.  
  635.         JMP     rsint_8530_status   ; Go send status
  636.  
  637. ;--------------------------------------------------------------------------;
  638. ; This code handles data characters                                        ;
  639. ;--------------------------------------------------------------------------;
  640.  
  641. rsint_8530_kt_data:
  642.  
  643.         CMP     BX,buffer_siz2      ; Will we overflow the buffer?
  644.         JA      rsint_8530_kt_done  ;      Yes.... Ignore the character
  645.  
  646.         MOV     DX,buffer_t_seg[SI] ; Get the buffer address
  647.         MOV     ES,DX               ;
  648.         OR      DX,DX               ; Is there one?
  649.         JNZ     rsint_8530_kt_sdata ;      Yes... Use it
  650.  
  651.         MOV     DL,AL               ; Save incoming data
  652.         CALL    get_a_buffer        ; Get the new buffer for the chain
  653.         OR      AX,AX               ; Did we find one?
  654.         JZ      rsint_8530_kt_done ;      NO.. Ignore the character
  655.  
  656.         MOV     buffer_t_seg[SI],AX ; Set the buffer address
  657.         MOV     ES,AX               ; Set the registers straight
  658.         MOV     AL,DL               ;
  659.  
  660. rsint_8530_kt_sdata:
  661.  
  662.         MOV     ES:0[BX],AL         ; Save the data byte
  663.  
  664.         INC     BX                  ; Bump counter and
  665.         MOV     buffer_t_in[SI],BX  ;      save
  666.  
  667. rsint_8530_kt_done:
  668.  
  669.         JMP     rsint_8530_status   ; Leave
  670.  
  671. ;==========================================================================;
  672. ; Receive a character in KISS mode                                         ;
  673. ;==========================================================================;
  674.  
  675. rsint_8530_kiss_r:
  676.  
  677. ;--------------------------------------------------------------------------;
  678. ; See if we have something in progress.  If we do then that is goodness.   ;
  679. ; If not we have to check the whole queue.  This simply shortcuts the      ;
  680. ; need to search the whole queue every time.                               ;
  681. ;--------------------------------------------------------------------------;
  682.  
  683.         MOV     ES,buffer_r_seg[SI] ; Get the shortcut buffer address
  684.         MOV     AX,ES               ; Now put it somewhere handy
  685.         OR      AX,AX               ; Anything there?
  686.         JNZ     rsint_8530_kr_do    ;      Yep... Take the shortcut
  687.  
  688. ;--------------------------------------------------------------------------;
  689. ; See if we have anything.  We loop here if nothing doing.  Enable         ;
  690. ; interrupts to permit something to work.                                  ;
  691. ;--------------------------------------------------------------------------;
  692.  
  693.         STI                         ; Interrupt enable
  694.  
  695. rsint_8530_kr_loop1:
  696.  
  697.         MOV     ES,buffer_r_a[SI]   ; Get the current buffer address
  698.         MOV     AX,ES:buffer_next   ; Get head of queue
  699.         OR      AX,AX               ; Anything in queue?
  700.         JZ      rsint_8530_kr_loop1 ;      Yep.. Go process it
  701.  
  702. ;--------------------------------------------------------------------------;
  703. ; Ok!  Something is here.. We now have to scurry down the queue to find    ;
  704. ; the last entry because it is the oldest!  Disable interrupts to prevent  ;
  705. ; someone from messing with it                                             ;
  706. ;--------------------------------------------------------------------------;
  707.  
  708.         CLI                         ; Interrupt disable
  709.  
  710.         MOV     ES,buffer_r_a[SI]   ; Get the current buffer address
  711.         MOV     BX,ES               ; Save this!
  712.         MOV     ES,ES:buffer_next   ; Get head of queue
  713.  
  714. rsint_8530_kr_loop2:
  715.  
  716.         MOV     AX,ES:buffer_next   ; Get --> to next in queue
  717.         OR      AX,AX               ; Anything there?
  718.         JZ      rsint_8530_kr_found ;      Nope..  Found end of queue
  719.         MOV     BX,ES               ; Save last
  720.         MOV     ES,AX               ; Point to next
  721.         JMP     rsint_8530_kr_loop2 ; Loop back for more
  722.  
  723. rsint_8530_kr_found:
  724.  
  725.         STI                         ; Reenable interrupts
  726.  
  727.         MOV     buffer_r_seg[SI],ES ; Set it up for shortcut next time.
  728.         JMP     SHORT rsint_8530_kr_fs ; Go send beginning FEND
  729.  
  730. ;--------------------------------------------------------------------------;
  731. ; ES now points to a buffer with our data in it.   Get current mode        ;
  732. ; and go to it.                                                            ;
  733. ;--------------------------------------------------------------------------;
  734.  
  735. rsint_8530_kr_do:
  736.  
  737.         MOV     BL,kiss_flag[SI]    ; Get the KISS-R mode
  738.         AND     BL,kiss_r_mode      ;
  739.         SUB     BH,BH               ;
  740.         JMP     DS:rsint_8530_krjmp[BX]  ; Go where we gotta go
  741.  
  742. rsint_8530_krjmp LABEL WORD         ; Branch table
  743.         DW OFFSET rsint_8530_kr_fs    ; 0 = Start packet FEND
  744.         DW OFFSET rsint_8530_kr_type  ; 1 = Type
  745.         DW OFFSET rsint_8530_kr_data  ; 2 = Data
  746.         DW OFFSET rsint_8530_kr_fe    ; 3 = End packet FEND
  747.  
  748. rsint_8530_kr_modes:                ; Subroutine to set KISS-R mode
  749.         MOV     AL,kiss_flag[SI]    ; Get the whole flag byte
  750.         AND     AL,0FFH-kiss_r_mode ; Remove the current mode setting
  751.         OR      AL,BL               ; Put new one in
  752.         MOV     kiss_flag[SI],AL    ; Put byte pack
  753.         RET                         ; Return to caller
  754.  
  755. ;--------------------------------------------------------------------------;
  756. ; Start a packet by sending FEND                                           ;
  757. ;--------------------------------------------------------------------------;
  758.  
  759. rsint_8530_kr_fs:                   ; Start packet FEND
  760.  
  761.         MOV     buffer_r_out[SI],0  ; Clear output pointer
  762.         MOV     BL,kiss_r_mtype     ; Set mode to data
  763.         CALL    rsint_8530_kr_modes ;
  764.         MOV     AX,kiss_fend        ; Output FEND.  We zero AH this way too..
  765.         JMP     rsint_8530_status_ah ; Go load AH status data.
  766.  
  767. ;--------------------------------------------------------------------------;
  768. ; Send the packet type                                                     ;
  769. ;--------------------------------------------------------------------------;
  770.  
  771. rsint_8530_kr_type:                 ; Start packet FEND
  772.  
  773.         MOV     AX,kiss_data        ; Signal data frame -- zero AX this way
  774.         MOV     BL,kiss_r_mdata     ; Set mode to data
  775.         CALL    rsint_8530_kr_modes ;
  776.         JMP     rsint_8530_status_ah ; Go load AH status data.
  777.  
  778. ;--------------------------------------------------------------------------;
  779. ; Send packet data.  Don't forget check for special characters             ;
  780. ;--------------------------------------------------------------------------;
  781.  
  782. rsint_8530_kr_data:                 ; Send packet data
  783.  
  784.         MOV     AX,kiss_fesc        ; Clear AH for call to status
  785.                                     ; Set AL to escape if needed
  786.  
  787.         MOV     BX,buffer_r_out[SI] ; Get output pointer
  788.         MOV     DL,ES:[BX]          ; Get a data byte
  789.  
  790.         CMP     DL,kiss_fend        ; Data is FEND?
  791.         JE      rsint_8530_kr_dfend ;      YES... Escape needed.
  792.  
  793.         CMP     DL,kiss_fesc        ; Data is FESC?
  794.         JE      rsint_8530_kr_dfesc ;      YES... Escape needed.
  795.  
  796.         MOV     AL,DL               ; Regular data, let it go
  797.         INC     BX                  ; Increment pointer
  798.         CMP     BX,ES:buffer_dl     ; Are we at the end of the data in buffer
  799.         JAE     rsint_8530_kr_end   ;      Yes....
  800.  
  801.         MOV     buffer_r_out[SI],BX ; Save new output pointer
  802.         JMP     rsint_8530_status_ah ; Go load AH status data.
  803.  
  804. ; End of buffer detected.
  805.  
  806. rsint_8530_kr_end:                  ; End of buffer but last data char in AL
  807.  
  808.         MOV     BL,kiss_r_mfe       ; Set mode to ending FEND
  809.         CALL    rsint_8530_kr_modes ;
  810.         JMP     rsint_8530_status_ah ; Go load AH status data.
  811.  
  812. ; FEND found in data
  813.  
  814. rsint_8530_kr_dfend:                ; FEND in data stream
  815.  
  816.         MOV     BYTE PTR ES:[BX],kiss_tfend  ; Make the data a transposed FEND
  817.                                     ; AL already has an FESC in it.  Don't
  818.                                     ; bump the pointer so we will send TFEND
  819.         JMP     rsint_8530_status_ah ; Go load AH status data.
  820.  
  821. ; FESC found in data
  822.  
  823. rsint_8530_kr_dfesc:                ; FESC in data stream
  824.  
  825.         MOV     BYTE PTR ES:[BX],kiss_tfesc  ; Make the data a transposed FESC
  826.                                     ; AL already has an FESC in it.  Don't
  827.                                     ; bump the pointer so we will send TFESC
  828.         JMP     rsint_8530_status_ah ; Go load AH status data.
  829.  
  830. ;--------------------------------------------------------------------------;
  831. ; Send ending FEND and free everything up                                  ;
  832. ;--------------------------------------------------------------------------;
  833.  
  834. rsint_8530_kr_fe:
  835.  
  836.         MOV     buffer_r_out[SI],0  ; Clear output pointer
  837.         MOV     buffer_r_seg[SI],0  ; Clear shortcut buffer address
  838.  
  839.         CLI                         ; Disable interrupts
  840.  
  841.         MOV     ES,buffer_r_a[SI]   ; Get the current buffer address
  842.         MOV     BX,ES               ;
  843.  
  844. rsint_8530_kr_feloop1:
  845.  
  846.         MOV     AX,ES:buffer_next   ; Get --> to next in queue
  847.         OR      AX,AX               ; Anything there?
  848.         JZ      rsint_8530_kr_fefnd ;   Nope..  Found end of queue
  849.         MOV     BX,ES               ; Save last
  850.         MOV     ES,AX               ; Point to next
  851.         JMP     rsint_8530_kr_feloop1 ; Loop back for more
  852.  
  853. rsint_8530_kr_fefnd:
  854.  
  855.                                     ; ES = address of buffer we are finishing
  856.                                     ; BX = buffer that points to one in ES
  857.  
  858.         MOV     AX,ES               ; Free this buffer
  859.         CALL    free_a_buffer       ; Free a buffer instead
  860.  
  861.         MOV     ES,BX               ; Go back one buffer
  862.         MOV     ES:buffer_next,0    ;      and zero his pointer
  863.  
  864.         STI                         ; Reenable interrupts
  865.  
  866.         MOV     AX,kiss_fend        ; Send FEND
  867.         JMP     rsint_8530_status_ah ; Go load AH status data.
  868.  
  869. ;==========================================================================;
  870. ; Send a packet -- ES points to buffer to be sent.                         ;
  871. ;==========================================================================;
  872.  
  873. rsint_8530_sendp:
  874.  
  875.         MOV     ES:buffer_next,0    ; Put a zero in next buffer address
  876.  
  877. ;--------------------------------------------------------------------------;
  878. ; See if queue is empty.  If so this packet is the whole queue.  We also   ;
  879. ; need to attempt to turn on the transmitter                               ;
  880. ;--------------------------------------------------------------------------;
  881.  
  882.         MOV     AX,buffer_t_a[SI]   ; Get the transmit buffer address
  883.         OR      AX,AX               ; Is there one?
  884.         JNZ     rsint_8530_sendp_q  ;      Yes.  Must add this packet to the q
  885.  
  886. ; This buffer is the whole queue.  Put at the head
  887.  
  888.         MOV     buffer_t_a[SI],ES   ; Put this buffer on head of queue
  889.         MOV     ES:buffer_next,AX   ; Put a zero in next buffer address
  890.  
  891. ; Now try to turn on the transmitter
  892.  
  893.         TEST    flags[SI],flags_xmt_on ; Transmitter on?
  894.         JNZ     rsint_8530_sendp_x  ;     Yes.. Don't do anything
  895.         TEST    options[SI],opt_fd  ; Full duplex?
  896.         JNZ     rsint_8530_sendp_t  ;     Yes.. Go turn on transmitter
  897.         TEST    flags[SI],flags_dcd_on ; DCD on?
  898.         JNZ     rsint_8530_sendp_x  ;     Yes.. Don't do anything
  899.  
  900.         MOV     AX,timer_dcd[SI]    ; Get timer
  901.         CMP     AL,value_slot[SI]   ; Slot expired?
  902.         JB      rsint_8530_sendp_x  ;     No... Don't do anything
  903.  
  904.         CALL    random              ; Get a random number
  905.         CMP     AL,value_p[SI]      ; Check against "P" (the probability)
  906.         JA      rsint_8530_sendp_x  ;     Too big... Don't do anything
  907.  
  908. ; Turn on transmitter
  909.  
  910. rsint_8530_sendp_t:                 ;
  911.  
  912.         MOV     DX,baseaddr[SI]     ; Get port address
  913.         CALL    ton_clk_8530        ; Call the transmitter routine
  914.  
  915. ; Do nothing
  916.  
  917. rsint_8530_sendp_x:                 ;
  918.  
  919.         JMP     rsint_exit          ; Leave
  920.  
  921. ;--------------------------------------------------------------------------;
  922. ; Add this packet to the transmit queue.                                   ;
  923. ;--------------------------------------------------------------------------;
  924.  
  925. rsint_8530_sendp_q:                 ;
  926.  
  927.         MOV     BX,ES               ; Save address of buffer to add to queue
  928.  
  929. ; Loop around to find end of chain
  930.  
  931. rsint_8530_sendp_loop:
  932.  
  933.         MOV     ES,AX               ; Address of buffer to test
  934.         MOV     AX,ES:buffer_next   ; Get next one in chain
  935.         OR      AX,AX               ; Anything left?
  936.         JNZ     rsint_8530_sendp_loop ;    Yep..  Try again
  937.  
  938.         MOV     ES:buffer_next,BX   ; Add to chain
  939.  
  940.         JMP     rsint_exit          ; Leave
  941.  
  942. ;==========================================================================;
  943. ; Receive a packet                                                         ;
  944. ;==========================================================================;
  945.  
  946. rsint_8530_recvp:
  947.  
  948. ;--------------------------------------------------------------------------;
  949. ; See if we have anything.  We loop here if nothing doing.  Enable         ;
  950. ; interrupts to permit something to work.                                  ;
  951. ;--------------------------------------------------------------------------;
  952.  
  953.         STI                         ; Interrupt enable
  954.  
  955. rsint_8530_recvp_loop1:
  956.  
  957.         MOV     ES,buffer_r_a[SI]   ; Get the current buffer address
  958.         MOV     AX,ES:buffer_next   ; Get head of queue
  959.         OR      AX,AX               ; Anything in queue?
  960.         JZ      rsint_8530_recvp_loop1 ;   Yep.. Go process it
  961.  
  962. ;--------------------------------------------------------------------------;
  963. ; Ok!  Something is here.. We now have to scurry down the queue to find    ;
  964. ; the last entry because it is the oldest!  Disable interrupts to prevent  ;
  965. ; someone from messing with it                                             ;
  966. ;--------------------------------------------------------------------------;
  967.  
  968.         CLI                         ; Interrupt disable
  969.  
  970.         MOV     ES,buffer_r_a[SI]   ; Get the current buffer address
  971.         MOV     BX,ES               ; Save this!
  972.         MOV     ES,ES:buffer_next   ; Get head of queue
  973.  
  974. rsint_8530_recvp_loop2:
  975.  
  976.         MOV     AX,ES:buffer_next   ; Get --> to next in queue
  977.         OR      AX,AX               ; Anything there?
  978.         JZ      rsint_8530_recvp_done  ;   Nope..  Found end of queue
  979.         MOV     BX,ES               ; Save last
  980.         MOV     ES,AX               ; Point to next
  981.         JMP     rsint_8530_recvp_loop2 ; Loop back for more
  982.  
  983. rsint_8530_recvp_done:
  984.  
  985. ;--------------------------------------------------------------------------;
  986. ; Found the last item in the chain.  Remove it from the queue and give     ;
  987. ; it back to the user!                                                     ;
  988. ;--------------------------------------------------------------------------;
  989.  
  990.         MOV     AX,ES               ; This is the guy with the oldest data
  991.         MOV     ES,BX               ; Restore the old pointer.  This is the
  992.         MOV     ES:buffer_next,0    ; guy who contains the pointer we must zero!
  993.  
  994. ;--------------------------------------------------------------------------;
  995. ; All done                                                                 ;
  996. ;--------------------------------------------------------------------------;
  997.  
  998.         JMP     rsint_exit          ;
  999.  
  1000. ;==========================================================================;
  1001. ; Status..                                                                 ;
  1002. ;==========================================================================;
  1003.  
  1004. rsint_8530_status:
  1005.  
  1006.         SUB     AX,AX               ; No status so far!
  1007.  
  1008. rsint_8530_status_ah:               ; This entry point used to set AH only.
  1009.                                     ; This is for when data is in AL.  AH
  1010.                                     ; must be zero to use this entry point.
  1011.  
  1012.         MOV     ES,buffer_r_a[SI]   ; Get the current rcvr buffer address
  1013.         MOV     BX,ES:buffer_next   ; Get head of queue
  1014.  
  1015.         OR      BX,BX               ; Any packets waiting in receive buffer?
  1016.         JZ      rsint_8530_statnor  ;      Nope...
  1017.         OR      AH,rcvbuf_8530      ;      Yep.... turn on low order bit
  1018. rsint_8530_statnor:                 ;
  1019.  
  1020.         MOV     BX,buffer_t_a[SI]   ; Get the current xmit buffer address
  1021.  
  1022.         AND     AH,txbuf_8530       ; Turn off the empty transmit bit
  1023.         OR      BX,BX               ; Any packets in transmit queue?
  1024.         JNZ     rsint_8530_statnot  ;      Yep....
  1025.         OR      AH,0FFH-txbuf_8530  ; Turn on the empty transmit bit
  1026. rsint_8530_statnot:                 ;
  1027.  
  1028.         JMP     rsint_exit          ;
  1029.  
  1030. ;==========================================================================;
  1031. ; Buffer control - Get/Free                                                ;
  1032. ;==========================================================================;
  1033.  
  1034. rsint_8530_buff:
  1035.  
  1036.         MOV     AX,ES               ; Put it in parameter register
  1037.         OR      AX,AX               ; Did user supply an address
  1038.         JZ      rsint_8530_get      ;      No..  Get him a buffer
  1039.  
  1040.         CALL    free_a_buffer       ; Free a buffer instead
  1041.         JMP     rsint_exit          ;
  1042.  
  1043. rsint_8530_get:
  1044.         CALL    get_a_buffer        ;
  1045.         JMP     rsint_exit          ;
  1046.  
  1047. ;==========================================================================;
  1048. ; Set Timing values.. TXD, P, SLOT, CRC wait                               ;
  1049. ;==========================================================================;
  1050.  
  1051. rsint_8530_txd:
  1052.         SUB     AH,AH               ; Clear high order byte
  1053.         MOV     value_txd[SI],AX    ; Set value
  1054.         JMP     rsint_exit          ;
  1055.  
  1056. rsint_8530_setp:
  1057.         OR      AL,AL               ; Can't set zero!
  1058.         JZ      rsint_8530_setp_0   ;
  1059.         MOV     value_p[SI],AL      ; Set value
  1060. rsint_8530_setp_0:                  ;
  1061.         JMP     rsint_exit          ;
  1062.  
  1063. rsint_8530_slot:
  1064.         MOV     value_slot[SI],AL   ; Set value
  1065.         JMP     rsint_exit          ;
  1066.  
  1067. rsint_8530_crcwt:
  1068.         SUB     AH,AH               ; Clear high order byte
  1069.         MOV     value_crc[SI],AX    ; Set value
  1070.         JMP     rsint_exit          ;
  1071.  
  1072. ;==========================================================================;
  1073. ;==========================================================================;
  1074. ;==========================================================================;
  1075. ; 8530 Service subroutines.  Used by both the Service and the interrupt    ;
  1076. ;      handlers                                                            ;
  1077. ;==========================================================================;
  1078.  
  1079. ;==========================================================================;
  1080. ; 8530 Interrupt control                                                   ;
  1081. ;==========================================================================;
  1082.  
  1083. int_8530:
  1084.  
  1085. ;--------------------------------------------------------------------------;
  1086. ; Basic setup for R15 is DCD.                                              ;
  1087. ;--------------------------------------------------------------------------;
  1088.  
  1089.         MOV     AL,sccreg15         ; Point at WR15
  1090.         OUT     DX,AL               ;
  1091.  
  1092.         MOV     AL,dcd_ie           ;
  1093.  
  1094. ;--------------------------------------------------------------------------;
  1095. ; If we have are receiving, want break/abort!                              ;
  1096. ;--------------------------------------------------------------------------;
  1097.  
  1098.         TEST    flags[SI],flags_dcd_on ; Receiver on?
  1099.         JZ      int_8530_no_rx1     ;      Nope..
  1100.  
  1101.         OR      AL,rxie_brk         ; Want abort/break!
  1102.  
  1103. int_8530_no_rx1:
  1104.  
  1105. ;--------------------------------------------------------------------------;
  1106. ; If we have are transmitting data then we want TX underruns               ;
  1107. ;--------------------------------------------------------------------------;
  1108.  
  1109.         TEST    flags[SI],flags_xmt_on ; Transmitter on?
  1110.         JZ      int_8530_no_tx1     ;      Nope..
  1111.         CMP     period_xmtr[SI],period_x_tx ; Event = sending data
  1112.         JNE     int_8530_no_tx1     ;      Nope..
  1113.  
  1114.         OR      AL,txie_eom         ; Add eom interrupt
  1115.  
  1116. int_8530_no_tx1:
  1117.  
  1118. ;--------------------------------------------------------------------------;
  1119. ; Now set R15                                                              ;
  1120. ;--------------------------------------------------------------------------;
  1121.  
  1122.         OUT     DX,AL               ;
  1123.  
  1124. ;--------------------------------------------------------------------------;
  1125. ; Basic setup for R1 is external                                           ;
  1126. ;--------------------------------------------------------------------------;
  1127.  
  1128.         MOV     AL,sccreg1          ; Point at WR1
  1129.         OUT     DX,AL               ;
  1130.  
  1131.         MOV     AL,exi_enab         ;
  1132.  
  1133. ;--------------------------------------------------------------------------;
  1134. ; If we are transmitting data then we want TX                              ;
  1135. ;--------------------------------------------------------------------------;
  1136.  
  1137.         TEST    flags[SI],flags_xmt_on ; Transmitter on?
  1138.         JZ      int_8530_no_tx2     ;      Nope..
  1139.         CMP     period_xmtr[SI],period_x_tx ; Event = sending data
  1140.         JNE     int_8530_no_tx2     ;      Nope..
  1141.  
  1142.         OR      AL,txi_enab         ; Add Tx Interrupt Master Enable
  1143.  
  1144. int_8530_no_tx2:
  1145.  
  1146. ;--------------------------------------------------------------------------;
  1147. ; If we are receiving data then we want RX                                 ;
  1148. ;--------------------------------------------------------------------------;
  1149.  
  1150.         TEST    flags[SI],flags_dcd_on ; Receiver on?
  1151.         JZ      int_8530_no_rx2     ;      Nope..
  1152.  
  1153.         OR      AL,rxi_all          ; Add Rx Interrupt Master Enable
  1154.  
  1155. int_8530_no_rx2:
  1156.  
  1157. ;--------------------------------------------------------------------------;
  1158. ; Now set R1                                                               ;
  1159. ;--------------------------------------------------------------------------;
  1160.  
  1161.         OUT     DX,AL               ;
  1162.  
  1163. ;--------------------------------------------------------------------------;
  1164. ; Done..                                                                   ;
  1165. ;--------------------------------------------------------------------------;
  1166.  
  1167.         RET                         ;
  1168.  
  1169. ;==========================================================================;
  1170. ; 8530 Ready receiver and clock -- Use only on initialization and on       ;
  1171. ;          half duplex links.  Will destroy timing...                      ;
  1172. ;                                                                          ;
  1173. ;          Type "B" card is assumed full-duplex as far as clocking.        ;
  1174. ;                                                                          ;
  1175. ; Seconadry entry point:                                                   ;
  1176. ;                                                                          ;
  1177. ; 8530 Ready receiver --  Does not destroy timing                          ;
  1178. ;==========================================================================;
  1179.  
  1180. ron_clk_8530:
  1181.  
  1182. ;--------------------------------------------------------------------------;
  1183. ; Setup 8530 -- Register 11 -- Oscillator                                  ;
  1184. ;                                                                          ;
  1185. ;   Type "A"                                                               ;
  1186. ;       For channel "B":                                                   ;
  1187. ;         Use Crystal, Clock both rx and tx from DPLL, output xtal on TRXC ;
  1188. ;       For channel "A":                                                   ;
  1189. ;         Use Clock both rx and tx from DPLL                               ;
  1190. ;                                                                          ;
  1191. ;   Type "B"                                                               ;
  1192. ;         Rx clock = DPLL, tx clock is RTXC, output BRG on TRXC            ;
  1193. ;--------------------------------------------------------------------------;
  1194.  
  1195.         MOV     AL,sccreg11         ; Point at WR11
  1196.         OUT     DX,AL               ;
  1197.  
  1198. ; Guess at type B
  1199.  
  1200.         MOV     AL,rxc_dpll+txc_rtxc+trxc_out+trxc_brg ; Type "B" card setting
  1201.  
  1202.         CMP     type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
  1203.         JNE     ron_clk_8530bb      ;      Nope.. Guessed right
  1204.  
  1205. ; Type "A" card setting
  1206.  
  1207.         TEST    DX,scc_chan_mask    ; Channel "A" or "B"
  1208.         JZ      ron_clk_8530b1      ;      "B"!
  1209.         MOV     AL,rxc_dpll+txc_dpll ; Setting for "A"
  1210.         JMP     SHORT ron_clk_8530bb ;
  1211. ron_clk_8530b1:
  1212.         MOV     AL,xtal_osc+rxc_dpll+txc_dpll+trxc_out+trxc_xtl ;
  1213.  
  1214. ; Output the clock setting
  1215.  
  1216. ron_clk_8530bb:
  1217.  
  1218.         OUT     DX,AL               ; Put out
  1219.  
  1220. ;--------------------------------------------------------------------------;
  1221. ; Setup 8530 -- Register 12 and 13                                         ;
  1222. ;         12 = Lower byte of divisor                                       ;
  1223. ;         13 = Upper byte of divisor                                       ;
  1224. ;                                                                          ;
  1225. ; For type "A" card with internal oscillator, use tables                   ;
  1226. ;                                                                          ;
  1227. ; For type "B" card with external oscillator, use the equation.            ;
  1228. ;                                                                          ;
  1229. ;            32*data_rate = 1 / (brg+2) * clock period                     ;
  1230. ;                                                                          ;
  1231. ;--------------------------------------------------------------------------;
  1232.  
  1233.         MOV     AL,sccreg12         ; Point at WR12
  1234.         OUT     DX,AL               ;
  1235.         MOV     BL,data_rate[SI]    ; Get the data rate
  1236.         SUB     BH,BH               ; Zero high order byte
  1237.         SHL     BL,1                ; *2 for a word lookup
  1238.  
  1239.         CMP     type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
  1240.         JNE     ron_clk_8530_bdiv   ;      Nope.. Guessed right
  1241.  
  1242. ron_clk_8530_adiv:                  ; Clock setting for 8530 Type "A" card
  1243.  
  1244.         MOV     AX,divx32_8530[BX]  ; Get the whole divisor
  1245.         JMP     SHORT ron_clk_8530_dive ; Go set the rate
  1246.  
  1247. ron_clk_8530_bdiv:                  ; Clock setting for 8530 Type "B" card
  1248.  
  1249.         PUSH    DX                  ; We are gonna lose him on the MUL/DIV
  1250.  
  1251.         MOV     AX,clock_8530[SI]   ; Get the clock frequency in Khz
  1252.         MUL     word_100            ; Multiply by hundred
  1253.         DIV     divdr_8530[BX]      ; Divide by datarate table (which is
  1254.         DEC     AX                  ; already divided by 10.  The result is
  1255.         DEC     AX                  ; the baud rate generator setting in AX
  1256.                                     ; but we still must subtract 2
  1257.         POP     DX                  ; Ooopss lost DX is shuffle so get it back
  1258.  
  1259. ron_clk_8530_dive:                  ; Divisor info in AX so set it
  1260.  
  1261.         OUT     DX,AL               ; Put out lower byte
  1262.  
  1263.         MOV     AL,sccreg13         ; Point at WR13
  1264.         OUT     DX,AL               ;
  1265.         MOV     AL,AH               ; Get the upper divisor
  1266.         OUT     DX,AL               ; Put out lower byte
  1267.  
  1268. ;--------------------------------------------------------------------------;
  1269. ; Setup 8530 -- Register 14 -- DPLL                                        ;
  1270. ;         This register has both commands and bit functions                ;
  1271. ;         1)  NRZI mode                                                    ;
  1272. ;         2)  DPLL source = BRG                                            ;
  1273. ;         3)  Start the BRG                                                ;
  1274. ;                                                                          ;
  1275. ;    If type "B" card, keep selecting BRG in from PCC                      ;
  1276. ;                                                                          ;
  1277. ;    The rest of WR14 setup happens after the Secondary Entry Point!       ;
  1278. ;                                                                          ;
  1279. ;--------------------------------------------------------------------------;
  1280.  
  1281.         SUB     AH,AH               ; Assume type "A" card
  1282.  
  1283.         CMP     type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
  1284.         JE      ron_clk_8530_brgrtxc1 ;      Yep..
  1285.  
  1286.         MOV     AH,brg_clck         ; Set BRG clock in = PCC
  1287.  
  1288. ron_clk_8530_brgrtxc1:              ; Come here when BRG source is RTXC
  1289.  
  1290.         MOV     AL,sccreg14         ; Point at WR14
  1291.         OUT     DX,AL               ;
  1292.         MOV     AL,mod_nrzi         ; Command -> NRZI
  1293.         OR      AL,AH               ; BRG source bit as determined above
  1294.         OUT     DX,AL               ;
  1295.  
  1296.         MOV     AL,sccreg14         ; Point at WR14
  1297.         OUT     DX,AL               ;
  1298.         MOV     AL,dpll_brg         ; Command -> DPLL source = BRG
  1299.         OR      AL,AH               ; BRG source bit as determined above
  1300.         OUT     DX,AL               ;
  1301.  
  1302.         MOV     AL,sccreg14         ; Point at WR14
  1303.         OUT     DX,AL               ;
  1304.         MOV     AL,enab_brg         ; Start BRG
  1305.         OR      AL,AH               ; BRG source bit as determined above
  1306.         OUT     DX,AL               ;
  1307.  
  1308. ;--------------------------------------------------------------------------;
  1309. ; Secondary entry point is here.  This is used to start receiving when     ;
  1310. ; DCD appears for example!  It assumes the clocks are already set.         ;
  1311. ;--------------------------------------------------------------------------;
  1312.  
  1313. ron_8530:
  1314.  
  1315. ;--------------------------------------------------------------------------;
  1316. ; Setup 8530 -- Register 14 -- DPLL                                        ;
  1317. ;         This register has both commands and bit functions                ;
  1318. ;         1)  Put DPLL in search mode.  Start the BRG                      ;
  1319. ;--------------------------------------------------------------------------;
  1320.  
  1321.         SUB     AH,AH               ; Assume type "A" card
  1322.  
  1323.         CMP     type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
  1324.         JE      ron_clk_8530_brgrtxc2 ;      Yep..
  1325.  
  1326.         MOV     AH,brg_clck         ; Set BRG clock in = PCC
  1327.  
  1328. ron_clk_8530_brgrtxc2:              ; Come here when BRG source is RTXC
  1329.  
  1330.         MOV     AL,sccreg14         ; Point at WR14
  1331.         OUT     DX,AL               ;
  1332.         MOV     AL,dpllsrch+enab_brg ; Command -> DPLL search + start BRG
  1333.         OR      AL,AH               ; BRG source bit as determined above
  1334.         OUT     DX,AL               ;
  1335.  
  1336. ;--------------------------------------------------------------------------;
  1337. ; Setup 8530 -- Register 0 and 3                                           ;
  1338. ;            Use the write to WR0 to reset the receive CRC also            ;
  1339. ;                                                                          ;
  1340. ;            8 bits for receive, rx CRC enable.  If DCD active then        ;
  1341. ;            add hunting and rx enable.                                    ;
  1342. ;--------------------------------------------------------------------------;
  1343.  
  1344.         MOV     AL,rst_rcrc         ; Reset RX CRC
  1345.         OUT     DX,AL               ;
  1346.  
  1347.         MOV     AL,sccreg3          ; Point at WR3
  1348.         OUT     DX,AL               ;
  1349.  
  1350.         MOV     AL,rx_8bits+rx_crcon ;
  1351.         TEST    flags[SI],flags_dcd_on ; DCD on?
  1352.         JZ      ron_8530_nodcd1     ;      Nope
  1353.         OR      AL,hunt_on+rx_enabl ;      Yep..  Enable Rx and hunt
  1354. ron_8530_nodcd1:                    ;
  1355.  
  1356.         OUT     DX,AL               ;
  1357.  
  1358. ;--------------------------------------------------------------------------;
  1359. ; Setup Interrupt control and go                                           ;
  1360. ;--------------------------------------------------------------------------;
  1361.  
  1362.         CALL    int_8530            ;
  1363.  
  1364.         RET                         ; Done
  1365.  
  1366. ;==========================================================================;
  1367. ; 8530 Off -- Disable this port on the 8530.                               ;
  1368. ;==========================================================================;
  1369.  
  1370. off_8530:
  1371.  
  1372.         MOV     AL,sccreg1          ; Point at WR1
  1373.         OUT     DX,AL               ;
  1374.         SUB     AL,AL               ;
  1375.         OUT     DX,AL               ; Put out
  1376.  
  1377.         MOV     AL,sccreg15         ; Now to WR15
  1378.         OUT     DX,AL               ;
  1379.         SUB     AL,AL               ; Disable all interrupts!
  1380.         OUT     DX,AL               ;
  1381.  
  1382.         RET                         ;
  1383.  
  1384. ;==========================================================================;
  1385. ; 8530 Ready transmitter and clock.                                        ;
  1386. ;     Type "A" card:                                                       ;
  1387. ;          For half duplex lines, switch crystal and slow down             ;
  1388. ;          Full duplex uses DPLL timing so don't mess with clocks          ;
  1389. ;     Type "B" card:                                                       ;
  1390. ;          The output of the BRG is routed thru an external divide-by-32   ;
  1391. ;          circuit and then used as the transmitter clock.  No changes     ;
  1392. ;          are needed when going from receive to transmit and vice versa.  ;
  1393. ;==========================================================================;
  1394.  
  1395. ton_clk_8530:
  1396.  
  1397.         CMP     type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
  1398.         JNZ     ton_clk_8530_fd     ;      No... Dont mess with clocks
  1399.  
  1400.         TEST    options[SI],opt_fd  ; Full duplex?
  1401.         JNZ     ton_clk_8530_fd     ;      Yes.. Dont mess with clocks
  1402.  
  1403. ;--------------------------------------------------------------------------;
  1404. ; Setup 8530 -- Register 11 -- Oscillator                                  ;
  1405. ;       Use Crystal, Clock both rx and tx from BRG, output xtal on TRXC    ;
  1406. ;--------------------------------------------------------------------------;
  1407.  
  1408.         MOV     AL,sccreg11         ; Point at WR11
  1409.         OUT     DX,AL               ;
  1410.         TEST    DX,scc_chan_mask    ; Channel "A" or "B"
  1411.         JZ      ton_clk_8530b1      ;      "B"!
  1412.         MOV     AL,rxc_brg+txc_brg  ; Setting for "A"
  1413.         JMP     SHORT ton_clk_8530bb ;
  1414. ton_clk_8530b1:
  1415.         MOV     AL,xtal_osc+rxc_brg+txc_brg+trxc_out+trxc_xtl ;
  1416. ton_clk_8530bb:
  1417.         OUT     DX,AL               ; Put out
  1418.  
  1419. ;--------------------------------------------------------------------------;
  1420. ; Setup 8530 -- Register 12 and 13                                         ;
  1421. ;         12 = Lower byte of divisor                                       ;
  1422. ;         13 = Upper byte of divisor                                       ;
  1423. ;--------------------------------------------------------------------------;
  1424.  
  1425.         MOV     AL,sccreg12         ; Point at WR12
  1426.         OUT     DX,AL               ;
  1427.         MOV     BL,data_rate[SI]    ; Get the data rate
  1428.         SUB     BH,BH               ; Zero high order byte
  1429.         SHL     BL,1                ; *2 for a word lookup
  1430.         MOV     AX,divx1_8530[BX]   ; Get the whole divisor
  1431.         OUT     DX,AL               ; Put out lower byte
  1432.  
  1433.         MOV     AL,sccreg13         ; Point at WR13
  1434.         OUT     DX,AL               ;
  1435.         MOV     AL,AH               ; Get the upper divisor
  1436.         OUT     DX,AL               ; Put out lower byte
  1437.  
  1438. ;--------------------------------------------------------------------------;
  1439. ; Setup 8530 -- Register 14 -- DPLL                                        ;
  1440. ;         This register has both commands and bit functions                ;
  1441. ;         Start brg                                                        ;
  1442. ;--------------------------------------------------------------------------;
  1443.  
  1444.         MOV     AL,sccreg14         ; Point at WR14
  1445.         OUT     DX,AL               ;
  1446.         MOV     AL,enab_brg         ; Start BRG
  1447.         OUT     DX,AL               ; Note: Didn't woory about BRG source
  1448.                                     ; Since we don't got thru this code for
  1449.                                     ; A type "B" card
  1450.  
  1451. ;--------------------------------------------------------------------------;
  1452. ; Next code is common for both Full and Half Duplex                        ;
  1453. ;--------------------------------------------------------------------------;
  1454.  
  1455. ton_clk_8530_fd:
  1456.  
  1457. ;--------------------------------------------------------------------------;
  1458. ; Setup 8530 -- Register 5 -- Transmitter control                          ;
  1459. ;            DTR, 8bits, TX enable, RTS, CRC                               ;
  1460. ;--------------------------------------------------------------------------;
  1461.  
  1462.         MOV     AL,sccreg5          ; Point at WR5
  1463.         OUT     DX,AL               ;
  1464.  
  1465.         MOV     AL,dtr_pin+tx_8bits+tx_enabl+rts_pin+tx_crcen ;
  1466.         OUT     DX,AL               ;
  1467.  
  1468. ;--------------------------------------------------------------------------;
  1469. ; Set flags and stuff                                                      ;
  1470. ;--------------------------------------------------------------------------;
  1471.  
  1472.         OR      flags[SI],flags_xmt_on ; Transmitter on!
  1473.  
  1474.         MOV     period_xmtr[SI],period_x_txd ; Event = TXD delay
  1475.  
  1476.         MOV     timer_xmtr[SI],0    ; Set transmitter timer to zero
  1477.  
  1478. ;--------------------------------------------------------------------------;
  1479. ; Setup Interrupt control and go                                           ;
  1480. ;--------------------------------------------------------------------------;
  1481.  
  1482.         CALL    int_8530            ;
  1483.  
  1484.         RET                         ;
  1485.